class ShieldSentinel extends BaseSentinel
placeable;

var() int ShieldAmount;
var() int RegenRate;
var() sound AbsorbSound, DrainedSound;

var BigShieldSphere ShieldSphere;
var float LastHitTime;
var ShieldMesh CannonBase;
var float ShieldDrawScale;

struct HitDataStruct
{
	var vector HitLocation;
	var vector HitNormal;
};

var HitDataStruct HitData;
var byte HitCount, LastHitCount;

replication
{
    reliable if (Role == Role_Authority)
        ShieldAmount,ShieldSphere;
	unreliable if(Role == ROLE_Authority)
		HitCount, HitData;
	reliable if (Role < Role_Authority)
	   ShieldDrawScale;
}

function spawnShield()
{
    ShieldSphere = spawn(class'BigShieldSphere', self);
    ShieldSphere.Shield=self;
    ShieldSphere.SetLocation(Location + CentreOffset);
    ShieldSphere.SetDrawScale(ShieldDrawScale);
}

simulated function PostBeginPlay()
{
	super.PostBeginPlay();
    spawnShield();
	if(Level.NetMode != NM_DedicatedServer)
	{
		CannonBase = Spawn(class'ShieldMesh', , , location+vect(0,0,-40));
		CannonBase.SetBase(self);
	}
	SetTimer(0.2, true);
}


event TakeDamage(int Damage, Pawn EventInstigator, vector HitLocation, vector Momentum, class<DamageType> DamageType)
{
    local playercontroller pc;
    local controller p;
    local int num, i;

    spri=SentinelPlayerReplicationInfo(self.PlayerReplicationInfo);

	if(Role < ROLE_Authority || bTearOff || Health <= 0)
		return;

	//Ion Cannon are wimpy, so give them a little help.
	if(DamageType == class'DamTypeIonBlast')
		Damage *= 2;

	if(EventInstigator != None && Controller != None && Controller.SameTeamAs(EventInstigator.Controller) && TeamGame(Level.Game) != None)
		Damage *= TeamGame(Level.Game).FriendlyFireScale;

	//Let upgrades handle damage.

	Health -= Damage;

    if(damage>0)
    {
	    num=fmin(damage/3,20);
        if(level.bdropdetail) num/=2;

        for(i=0; i<num; i++)
	    {
            //if ( EffectIsRelevant(hitlocation,false) )
            //{
                spawn(class'TaskForces.tfStationSparks',,,hitlocation,rotator(Normal(hitlocation - location)));
            //}
        }

        for ( P = Level.ControllerList; P!=None; P=P.nextController )
        {
            pc=playercontroller(p);

            if(pc!=none && p.PlayerReplicationInfo.Team.TeamIndex==myteam)
               pc.ReceiveLocalizedMessage(class'TaskForces.tfSentinelDmgMsg',damage,,,self);
        }
    }

	if(Health <= 0)
	{
		if(EventInstigator != None)
			Died(EventInstigator.Controller, DamageType, HitLocation);
		else
			Died(None, DamageType, HitLocation);
	}

	else
	{
		PlayHit(Damage, EventInstigator, HitLocation, DamageType, Momentum);

		if(Controller != None)
			Controller.NotifyTakeHit(EventInstigator, HitLocation, Damage, DamageType, Momentum);
    }
	if(EventInstigator!=none)
    {
        if(EventInstigator.playerreplicationinfo.team.teamindex==myteam)
        {
            EventInstigator.playerreplicationinfo.score-=float(damage)/200;
            tfpri(EventInstigator.playerreplicationinfo).SubSkill(-float(damage)/10);
        }
        else
        {
            EventInstigator.playerreplicationinfo.score+=float(damage)/200;
            tfpri(EventInstigator.playerreplicationinfo).AddSkill(float(damage)/10);
        }
    }
}

simulated function HitEffects()
{
	PlaySound(AbsorbSound);
	spawn(class'ShieldHitEffect',,, HitData.HitLocation, rotator(HitData.HitNormal));
}

simulated event PostNetReceive()
{
	if(HitCount != LastHitCount)
	{
		HitEffects();
		LastHitCount = HitCount;
	}
}

function Timer()
{
    if(ShieldSphere!=none)
    {
        if(ShieldAmount<default.ShieldAmount)
            ShieldAmount=min(ShieldAmount+RegenRate,default.ShieldAmount);
    }
    else
    {
        spawnShield();
    	ShieldAmount=RegenRate;
    }
    setTimer(0.2,true);
}

function ShieldAbsorbDmg(int Damage, Pawn EventInstigator, vector HitLocation, vector Momentum, class<DamageType> DamageType)
{
    local int dmg;
    dmg=Damage;
    if(Role < ROLE_Authority || bTearOff || Health <= 0)
		return;

    SetTimer(10.0, true);

	//Ion Cannon are wimpy, so give them a little help.
	if(DamageType == class'DamTypeIonBlast')
		dmg *= 2;

	if(EventInstigator != None && Controller != None && Controller.SameTeamAs(EventInstigator.Controller) && TeamGame(Level.Game) != None)
		dmg *= TeamGame(Level.Game).FriendlyFireScale;

    ShieldAmount -= dmg;

	if(ShieldAmount > 0)
	{
		Damage = 0;

		if(Level.TimeSeconds - LastHitTime > 0.1)
		{
			HitCount++;
			HitData.HitLocation = ShieldSphere.Location + normal(HitLocation - Location) * 64 * ShieldSphere.DrawScale;
			HitData.HitNormal = HitLocation - ShieldSphere.Location;

			if(Level.NetMode != NM_DedicatedServer)
				HitEffects();

			LastHitTime = Level.TimeSeconds;
		}
	}
	else
	{
		Damage = Abs(ShieldAmount);
		PlaySound(DrainedSound);
//        ShieldDrawScale=ShieldSphere.DrawScale;
		ShieldSphere.Destroy();
		ShieldSphere=none;
		tfgri(level.game.gamereplicationinfo).control[myteam]-=cost;
		ShieldAmount=0;
	}
	TakeDamage(Damage, EventInstigator, HitLocation, Momentum, DamageType);
}

simulated function Destroyed()
{
	if(ShieldSphere != None)
		ShieldSphere.Destroy();
	if(CannonBase != None)
		CannonBase.Destroy();

	Super.Destroyed();
}

function JumpOffPawn(){}


defaultproperties
{
    ShieldAmount=2000
    AbsorbSound=sound'TFMedia.ShieldAbsorb'
    DrainedSound=sound'TFMedia.ShieldDrained'
    RegenRate=20
    Health=100
    HealthMax=100
    mesh=none;
    bHardAttach=True
    Mass=100.000000
	Physics=PHYS_Falling
	CollisionRadius=10.000000
    CollisionHeight=40.000000
    Sname="Shield Sentinel"
    cost=300
    refControl=150
    ShieldDrawScale=3.0
}
